package com.multimedia.room.view;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import com.multimedia.room.R;


/**
 * Extended TextView to display long text lines. Part of the text
 * will be replaces by dots in the middle if view is not currently selected.
 * Otherwise marque effect will be used.
 * Please note, that it designed only for single-line content.
 * Multi-line property will be ignored as well as "ellipsize".
 */
public class LongTextView extends TextView {

    private static final String TAG = LongTextView.class.getSimpleName();
    private static final boolean DEBUG = false;
    private boolean mUnselected = false;
    private static final int MARQUEE_FOREVER = -1;

    private static final int MSG_SELECTED_ON = 1;
    private static final int MSG_SELECTED_OFF = 2;
    private static final int SELECT_DELAY = 1200;
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_SELECTED_ON:
                    setSelected(true);
                    break;
                case MSG_SELECTED_OFF:
                    setSelected(false);
                    // reset fading edge effect after Marquee stopped
                    setHorizontalFadingEdgeEnabled(true);
                    setFadingEdgeLength(getContext().getResources().getDimensionPixelSize(
                            R.dimen.text_fading_edge));
                    break;
            }
        }
    };

    public LongTextView(Context context) {
        super(context);
        init(context);
    }

    public LongTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public LongTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    @Override
    protected void drawableStateChanged() {
        super.drawableStateChanged();
        // brljyang: 2015-03-06
        // Using property of LAYER_TYPE_SOFTWARE on Android KK will cause
        // character flash when text marquee.
        // Using property of LAYER_TYPE_NONE will cause
        // the focus move slowly in collectionview in HiSi platform.
        // so change to use LAYER_TYPE_HARDWARE.
        setLayerType(LAYER_TYPE_HARDWARE, null);
        if (isSelected(getDrawableState())) {
            checkAndSetEllipsize(TextUtils.TruncateAt.MARQUEE);
        } else {
            checkAndSetEllipsize(null);
        }
    }

    private void checkAndSetEllipsize(TextUtils.TruncateAt where) {
        if (getEllipsize() != where) {
            setEllipsize(where);
            if (where == TextUtils.TruncateAt.MARQUEE) {
                setSelectedInt(true);
            } else {
                setSelectedInt(false);
            }
            if (DEBUG)
                Log.d(TAG, "id " + System.identityHashCode(this) + " changed to " + where.toString());
        }
    }

    private void init(Context context) {
        setEllipsize(null);
        setSingleLine(true);
        setHorizontallyScrolling(true);
        setHorizontalFadingEdgeEnabled(true);
        setFadingEdgeLength(context.getResources().getDimensionPixelSize(R.dimen.text_fading_edge));
        setMarqueeRepeatLimit(MARQUEE_FOREVER);
    }

    /**
     * Checks either view selected or not.
     *
     * @param states states array describing view drawable states.
     * @return true if view selected, false otherwise.
     */
    private boolean isSelected(int[] states) {
        for (int state : states) {
            if (state == android.R.attr.state_selected || state == android.R.attr.state_focused) {
                return true;
            }
        }
        return false;
    }

    private void setSelectedInt(boolean selected) {
        mHandler.removeMessages(MSG_SELECTED_ON);
        if (selected) {
            mHandler.sendEmptyMessageDelayed(MSG_SELECTED_ON, SELECT_DELAY);
        } else {
            mHandler.sendEmptyMessage(MSG_SELECTED_OFF);
        }
    }

    @Override
    protected void onVisibilityChanged(View changedView, int visibility) {
        super.onVisibilityChanged(changedView, visibility);
        if (getEllipsize() == TextUtils.TruncateAt.MARQUEE) {
            if (visibility != VISIBLE) {
                setSelectedInt(false);
                mUnselected = true;
            } else if (mUnselected) {
                setSelectedInt(true);
                mUnselected = false;
            }
            if (DEBUG)
                Log.d(TAG, "id " + System.identityHashCode(this) + " unselected " + mUnselected);
        }
    }

    //Overlay rule:fade. Disable left side's fade effect for text view.
    @Override
    protected float getLeftFadingEdgeStrength() {
        if (isSelected(getDrawableState())) {
            checkAndSetEllipsize(TextUtils.TruncateAt.MARQUEE);
            return super.getLeftFadingEdgeStrength();
        } else {
            checkAndSetEllipsize(null);
            return 0.0f;
        }
    }
}
